#include "SH_Mesh.h"
#include "SH_Manager.h"

SH_Mesh::SH_Mesh(QWidget *parent) : QWidget(parent) {
	
	borderMesh = QPen(QBrush(QColor(Qt::black)), sizeBorderMesh);
	borderQuad = QPen(QBrush(QColor(Qt::black)), sizeBorderQuad);
	borderCell = QPen(QBrush(QColor(Qt::black)), sizeBorderCell);
	
	
	currentCell = QPoint(0, 0);
	currentBrush = QBrush(QColor(Qt::yellow));
	
	resize(2 * sizeIndentMesh + 9 * sizeCell, 2 * sizeIndentMesh + 9 * sizeCell);
	setMinimumSize(2 * sizeIndentMesh + 9 * sizeCell, 2 * sizeIndentMesh + 9 * sizeCell);
	setMaximumSize(2 * sizeIndentMesh + 9 * sizeCell, 2 * sizeIndentMesh + 9 * sizeCell);
	
	manager = new SH_Manager;
	
}

SH_Mesh::~SH_Mesh() {
	delete manager;
}


void SH_Mesh::paintEvent(QPaintEvent *event) {
	
	markCell();
	drawNumbers();
	drawBorders();

}

void SH_Mesh::mousePressEvent(QMouseEvent *event) {

	// Так как QPoint::operator/ _округляет_ значение до ближайшего (вместо выделения дробной части),
	// то приходится извращаться: 
	currentCell.setX((event->pos() - QPoint(sizeIndentMesh, sizeIndentMesh)).x() / sizeCell);
	currentCell.setY((event->pos() - QPoint(sizeIndentMesh, sizeIndentMesh)).y() / sizeCell);
	
	update();
}

void SH_Mesh::keyPressEvent(QKeyEvent *event) {

	switch(event->key()) {
	
	case Qt::Key_Up:
		if(currentCell.y() != 0) currentCell.ry()--;
		break;
	case Qt::Key_Down:
		if(currentCell.y() != 8) currentCell.ry()++;
		break;
	case Qt::Key_Left:
		if(currentCell.x() != 0) currentCell.rx()--;
		break;
	case Qt::Key_Right:
		if(currentCell.x() != 8) currentCell.rx()++;
		break;
		
	case Qt::Key_1:
		manager->setValue(currentCell.y() * 9 + currentCell.x(), 1);
		break;
	case Qt::Key_2:
		manager->setValue(currentCell.y() * 9 + currentCell.x(), 2);
		break;
	case Qt::Key_3:
		manager->setValue(currentCell.y() * 9 + currentCell.x(), 3);
		break;
	case Qt::Key_4:
		manager->setValue(currentCell.y() * 9 + currentCell.x(), 4);
		break;
	case Qt::Key_5:
		manager->setValue(currentCell.y() * 9 + currentCell.x(), 5);
		break;
	case Qt::Key_6:
		manager->setValue(currentCell.y() * 9 + currentCell.x(), 6);
		break;
	case Qt::Key_7:
		manager->setValue(currentCell.y() * 9 + currentCell.x(), 7);
		break;
	case Qt::Key_8:
		manager->setValue(currentCell.y() * 9 + currentCell.x(), 8);
		break;
	case Qt::Key_9:
		manager->setValue(currentCell.y() * 9 + currentCell.x(), 9);
		break;

	case Qt::Key_0:
	case Qt::Key_Delete:
	case Qt::Key_Backspace:
		manager->setValue(currentCell.y() * 9 + currentCell.x(), 0);
		break;
		
	case Qt::Key_Space:
	case Qt::Key_Enter:
	case Qt::Key_Return:
		manager->solve();
		break;
		
	case Qt::Key_Escape:
		manager->~SH_Manager();
		manager = new SH_Manager();
		break;
	}
	
	update();
}


void SH_Mesh::drawBorders() {

	QPainter painter(this);
	
	// Рисование границ сетки
	for (int i = 0; i < 10; i++) {
		
		if (i % 3) painter.setPen(borderCell);
		else if (i % 9) painter.setPen(borderQuad);
		else painter.setPen(borderMesh);
		
		painter.drawLine(sizeIndentMesh + sizeCell * i, sizeIndentMesh, sizeIndentMesh + sizeCell * i, sizeIndentMesh + 9 * sizeCell);
		painter.drawLine(sizeIndentMesh, sizeIndentMesh + sizeCell * i, sizeIndentMesh + 9 * sizeCell, sizeIndentMesh + sizeCell * i);
	}
	painter.end();
	
}

void SH_Mesh::drawNumbers() {
	
	QPainter painter(this);

	for (int i = 0; i < 81; i++) {
		
		int val = manager->getValue(i); 
		
		if (val) {
			QFont font;
			font.setPointSize(sizeFont);
		
			painter.setPen(QPen());	
			painter.setFont(font);

			painter.drawText(QPoint(i % 9, i / 9 + 1) * sizeCell + QPoint(sizeIndentMesh, sizeIndentMesh) + QPoint(sizeIndentFontX, sizeIndentFontY), QString("%1").arg(val));
			
		}		
	}
	
	painter.end();
	
}

void SH_Mesh::markCell() {
	
	// Закраска текущей ячейки
	
	QPainter painter(this);
	
	painter.setBrush(currentBrush);
	painter.setPen(Qt::NoPen);
	
	painter.drawRect(QRect(currentCell * sizeCell + QPoint(sizeIndentMesh, sizeIndentMesh), (currentCell + QPoint(1, 1)) * sizeCell + QPoint(sizeIndentMesh, sizeIndentMesh)));
	
	painter.end();
	
}
